package wassalt.Utils;

import org.apache.http.HttpStatus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import wassalt.client.R;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

import android.util.Log;
import android.widget.Toast;

class HTTPReceiver extends BroadcastReceiver {

	private static final String NAME = "name";
	private static final String WHEN = "when";
	private static final String PLACE = "place";
	private static final String TYPE = "type";
	private static final Object TRUE = "true";
	Context mCtx;
	DbAdapter db;

	/**
	 * Constructor - Creates instances of objects needed for the HTTPReceiver
	 * 
	 * @author Aya Kamel
	 * @param mCtx
	 *            The current context
	 * @param db
	 *            The DbAdapter instance
	 */
	public HTTPReceiver(Context mCtx, DbAdapter db) {
		this.mCtx = mCtx;
		this.db = db;
	}

	/**
	 * Handles the responses for updating requests tables in the local database
	 * 
	 * @author Aya Kamel
	 * @param response
	 *            The response string from the server
	 */
	public void handleList(String response, int tab) {
		// Clear the table to be updated
		if (!db.isOpened)
			db.open();

		switch (tab) {
		case AppConstants.TAB_INCOMING:
			Log.i("Tracer", "Incoming response:" + response);
			db.clearIncoming();
			break;
		case AppConstants.TAB_OUTGOING:
			Log.i("Tracer", "Outgoing response:" + response);
			db.clearOutgoing();
			break;
		case AppConstants.TAB_SELF:
			Log.i("Tracer", "Self response:" + response);
			db.clearSelf();
			break;
		}

		// Re-insert each object retrieved from the response
		try {
			JSONArray jsonArray = new JSONArray(response);
			for (int i = 0; i < jsonArray.length(); i++) {
				JSONObject jsonObject = jsonArray.getJSONObject(i);
				db.createNotification(jsonObject, tab);
			}
		} catch (JSONException e) {
			// ToastError();
		}

		db.close();
	}

	/**
	 * Handles the responses for the data that requires user notification
	 * 
	 * @author Aya Kamel
	 * @param response
	 *            The response string from the server
	 * @param newReq
	 *            A boolean that represents whether it is a new request or a
	 *            fulfilled request
	 */
	public void handleNew(String response, boolean newReq) {
		Log.i("Tracer", "Response (New smth): " + response);
		JSONObject res = null;
		JSONArray jsonArray = null;
		try {
			res = new JSONObject(response);
			jsonArray = res.getJSONArray("myArrayList");
		} catch (JSONException e1) {
		}

		if (res != null && !jsonArray.toString().equals("[]")) {
			try {

				for (int i = 0; i < jsonArray.length(); i++) {

					// Analyze the object
					JSONObject obj = jsonArray.getJSONObject(i);
					String c_name = obj.getString(NAME);
					String duration = obj.getString(WHEN);
					String location = obj.getString(PLACE);
					boolean time = obj.getString(TYPE).equals(TRUE);

					CharSequence notification_text = "";
					CharSequence title = "";

					// Display the notification message according to the type of
					// the message
					if (!newReq) // This is an arrival
					{
						Log.i("Tracer", "NEW ARRIVAL");
						title = c_name + " "
								+ mCtx.getString(R.string.sys_bar_notif_title);
						if (!time)// time
							notification_text = c_name
									+ " "
									+ mCtx.getString(R.string.sys_bar_notif_now)
									+ " "
									+ duration
									+ " "
									+ mCtx.getString(R.string.sys_bar_notif_minsfrom)
									+ " " + location;
						else
							notification_text = c_name
									+ " "
									+ mCtx.getString(R.string.sys_bar_notif_now)
									+ " "
									+ duration
									+ " "
									+ mCtx.getString(R.string.sys_bar_notif_kmfrom)
									+ " " + location;

						Log.i("Tracer", "Notification title: " + title);
						Log.i("Tracer", "Notification text: "
								+ notification_text);

						int in = AppConstants.TAB_INCOMING;
						long req_id = Long.parseLong(obj.getString("req_id"));
						if (!db.isOpened)
							db.open();
						long rowId = db.rowIdByReqId(req_id, in);
						db.close();
						Log.e("ROWID", rowId+"");
						ClientServerCommunication.deleteRequestFromServer(
								obj.getString("req_id"), mCtx, rowId, in);
					} else // This is a new request
					{
						title = mCtx.getString(R.string.sys_bar_notif_new_req);
						if (time)
							notification_text = c_name
									+ mCtx.getString(R.string.sys_bar_notif_msg_prt1)
									+ duration
									+ mCtx.getString(R.string.sys_bar_notif_msg_prt2_d)
									+ location;
						else
							notification_text = c_name
									+ mCtx.getString(R.string.sys_bar_notif_msg_prt1)
									+ duration
									+ mCtx.getString(R.string.sys_bar_notif_msg_prt2_t)
									+ location;

						if (!db.isOpened)
							db.open();
						db.insertNotification(obj.getString("req_id"), c_name,
								"Pending", true, location, duration,
								obj.getString(TYPE),
								obj.getString("startDate"),
								obj.getString("endDate"),
								AppConstants.TAB_OUTGOING,
								obj.getString("phone"));
						db.close();
					}

					// Show notification
					StatusBarNotification.show(mCtx, title, notification_text);
				}
			} catch (Exception e) {
				// ToastError();
				Log.e("Tracer", "CAUGHT EXCEPTION " + e.getMessage());
			}
		}
	}

	/**
	 * When a broadcast message is received direct the message to the
	 * appropriate message handler
	 * 
	 * @author Aya Kamel
	 */
	@Override
	public void onReceive(Context context, Intent intent) {
		int http_status = intent.getExtras().getInt(AppConstants.HTTP_STATUS);
		String response = intent.getExtras().getString(
				AppConstants.HTTP_RESPONSE);
		Log.e("***El response", response);
		String action = intent.getAction();
		System.out.println(http_status);
		if (http_status == HttpStatus.SC_OK) {

			// When the refresh incoming was called
			if (action.equals(AppConstants.HTTP_IN_FILTER))
				handleList(response, AppConstants.TAB_INCOMING);
			else
			// When refresh outgoing was called
			if (action.equals(AppConstants.HTTP_OUT_FILTER))
				handleList(response, AppConstants.TAB_OUTGOING);
			else
			// When refresh self was called
			if (action.equals(AppConstants.HTTP_SELF_FILTER))
				handleList(response, AppConstants.TAB_SELF);
			else
			// When the getArrivals was called
			if (action.equals(AppConstants.HTTP_GETARRIVALS_FILTER)) {
				Log.e("*****ARRRIVALS", response);
				handleNew(response, false);
			} else
			// When the check was called
			if (action.equals(AppConstants.HTTP_CHECK_FILTER)) {
				Log.e("*****REQUESTSS", response);
				handleNew(response, true);
			}

			if (action.equals(AppConstants.HTTP_STATUS)) {
				Log.i("Tracer", "Status Update");
				long id = intent.getExtras().getLong("rowId");
				boolean val = intent.getExtras().getBoolean("value");
				if (!db.isOpened)
					db.open();
				db.setLocalStatus(id, val);
				db.close();
			}

			if (action.equals(AppConstants.HTTP_CANCEL_FILTER)
					|| action.equals(AppConstants.HTTP_DELETE_FILTER)) {
				Log.i("Tracer", "Remove notification");
				long id = intent.getExtras().getLong("rowId");
				int table = intent.getExtras().getInt("table");
				if (id != -1) {
					if (!db.isOpened)
						db.open();
					db.removeLocally(id, table);
					db.close();
				}

			}

		} else
			ToastError();

		// Declare that something was updated to refresh the tables
		Intent i = new Intent();
		i.setAction(AppConstants.UPDATE_TABLES);
		mCtx.sendBroadcast(i);

		abortBroadcast();
	}

	/**
	 * Shows a toast with an error message when the response indicates failure
	 * 
	 * @author Aya Kamel
	 */
	public void ToastError() {
		Toast.makeText(mCtx, mCtx.getString(R.string.error_toast), 0).show();
	}

}
